using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.ComponentModel;
using System.Xml;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace Pavilion
{
    public class Animation
    {
        public event Action<Animation> Disposed;
        public event NameChangedDelegate NameChanged;

        public string Name { get { return name; } set { SetName(value); } }
        public bool EnableLoading { get; set; }
        public Color Color { get; set; }
        public NotifiableCollection<Frame> FrameList { get; private set; }

        public int DefaultFrameWidth { get { return FrameList.Count == 0 ? 200 : FrameList[0].Width; } }
        public int DefaultFrameHeight { get { return FrameList.Count == 0 ? 200 : FrameList[0].Height; } }
        public Vector2 DefaultFrameOrigin { get { return FrameList.Count == 0 ? new Vector2(100, 100) : new Vector2(FrameList[0].OriginX, FrameList[0].OriginY); } }

        private string name;

        public Animation()
        {
            this.EnableLoading = true;
            this.Color = Color.White;
            this.FrameList = new NotifiableCollection<Frame>();
        }

        public Animation(IEnumerable<Frame> frameCollection) : this()
        {
            this.FrameList.AddRange(frameCollection);
        }

        public void Dispose()
        {
            UnloadAllFrames();
            FrameList.Clear();
            NameChanged = null;

            OnDispose();
            Disposed = null;
        }

        public void LoadAllFrames(string fullResourceBuildPath)
        {
            if (!EnableLoading)
                return;

            for (int i = 0; i < FrameList.Count; i++)
                LoadFrame(fullResourceBuildPath, i);
        }

        public void UnloadAllFrames()
        {
            if (!EnableLoading)
                return;

            for (int i = 0; i < FrameList.Count; i++)
                FrameList[i].Unload();
        }

        public void LoadFrame(string fullResourceBuildPath, int frameIndex)
        {
            if (EnableLoading)
                FrameList[frameIndex].Load(fullResourceBuildPath + Name + @"\" + frameIndex);
        }

        public void UnloadFrame(int frameIndex)
        {
            if (EnableLoading)
                FrameList[frameIndex].Unload();
        }

        public void Draw(int frameIndex, Vector2 position, float size, Vector2 origin, SpriteEffects effects)
        {
            if (FrameList.Count <= frameIndex)
                return;

            FrameList[frameIndex].Draw(position, Color, size, origin, effects);
        }

        public Frame CreateDefaultFrame()
        {
            Microsoft.Xna.Framework.Graphics.Texture2D texture = CTexture2D.CreateTexture(this.DefaultFrameWidth, this.DefaultFrameHeight);

            Frame frame = new Frame()
            {
                OriginX = this.DefaultFrameOrigin.X,
                OriginY = this.DefaultFrameOrigin.Y
            };

            frame.TextureList.Add(new CTexture2D(texture));

            return frame;
        }

        public override string ToString()
        {
            return Name;
        }

        private void SetName(string value)
        {
            if (name == value)
                return;

            string oldName = name;
            name = value;

            OnNameChanged(oldName, name);
        }

        private void OnNameChanged(string oldName, string newName)
        {
            if (NameChanged != null)
                NameChanged(oldName, newName);
        }

        private void OnDispose()
        {
            if (Disposed != null)
                Disposed(this);
        }
    }
}
